home *** CD-ROM | disk | FTP | other *** search
/ Software of the Month Club 2000 October / Software of the Month - Ultimate Collection Shareware 277.iso / pc / PROGRAMS / UTILITY / WINLINUX / DATA1.CAB / programs_-_kernel_source / FS / IOCTL.C < prev    next >
Encoding:
C/C++ Source or Header  |  1999-09-17  |  2.3 KB  |  108 lines

  1. /*
  2.  *  linux/fs/ioctl.c
  3.  *
  4.  *  Copyright (C) 1991, 1992  Linus Torvalds
  5.  */
  6.  
  7. #include <linux/mm.h>
  8. #include <linux/smp_lock.h>
  9. #include <linux/file.h>
  10.  
  11. #include <asm/uaccess.h>
  12.  
  13. static int file_ioctl(struct file *filp,unsigned int cmd,unsigned long arg)
  14. {
  15.     int error;
  16.     int block;
  17.     struct inode * inode = filp->f_dentry->d_inode;
  18.  
  19.     switch (cmd) {
  20.         case FIBMAP:
  21.             if (inode->i_op == NULL)
  22.                 return -EBADF;
  23.                 if (inode->i_op->bmap == NULL)
  24.                 return -EINVAL;
  25.             if ((error = get_user(block, (int *) arg)) != 0)
  26.                 return error;
  27.             block = inode->i_op->bmap(inode,block);
  28.             return put_user(block, (int *) arg);
  29.         case FIGETBSZ:
  30.             if (inode->i_sb == NULL)
  31.                 return -EBADF;
  32.             return put_user(inode->i_sb->s_blocksize, (int *) arg);
  33.         case FIONREAD:
  34.             return put_user(inode->i_size - filp->f_pos, (int *) arg);
  35.     }
  36.     if (filp->f_op && filp->f_op->ioctl)
  37.         return filp->f_op->ioctl(inode, filp, cmd, arg);
  38.     return -ENOTTY;
  39. }
  40.  
  41.  
  42. asmlinkage int sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
  43. {    
  44.     struct file * filp;
  45.     unsigned int flag;
  46.     int on, error = -EBADF;
  47.  
  48.     lock_kernel();
  49.     filp = fget(fd);
  50.     if (!filp)
  51.         goto out;
  52.     error = 0;
  53.     switch (cmd) {
  54.         case FIOCLEX:
  55.             FD_SET(fd, ¤t->files->close_on_exec);
  56.             break;
  57.  
  58.         case FIONCLEX:
  59.             FD_CLR(fd, ¤t->files->close_on_exec);
  60.             break;
  61.  
  62.         case FIONBIO:
  63.             if ((error = get_user(on, (int *)arg)) != 0)
  64.                 break;
  65.             flag = O_NONBLOCK;
  66. #ifdef __sparc__
  67.             /* SunOS compatibility item. */
  68.             if(O_NONBLOCK != O_NDELAY)
  69.                 flag |= O_NDELAY;
  70. #endif
  71.             if (on)
  72.                 filp->f_flags |= flag;
  73.             else
  74.                 filp->f_flags &= ~flag;
  75.             break;
  76.  
  77.         case FIOASYNC:
  78.             if ((error = get_user(on, (int *)arg)) != 0)
  79.                 break;
  80.             flag = on ? FASYNC : 0;
  81.  
  82.             /* Did FASYNC state change ? */
  83.             if ((flag ^ filp->f_flags) & FASYNC) {
  84.                 if (filp->f_op && filp->f_op->fasync)
  85.                     filp->f_op->fasync(fd, filp, on); 
  86.             }
  87.             if (on)
  88.                 filp->f_flags |= FASYNC;
  89.             else
  90.                 filp->f_flags &= ~FASYNC;
  91.             break;
  92.  
  93.         default:
  94.             error = -ENOTTY;
  95.             if (!filp->f_dentry || !filp->f_dentry->d_inode)
  96.                 error = -ENOENT;
  97.             else if (S_ISREG(filp->f_dentry->d_inode->i_mode))
  98.                 error = file_ioctl(filp, cmd, arg);
  99.             else if (filp->f_op && filp->f_op->ioctl)
  100.                 error = filp->f_op->ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
  101.     }
  102.     fput(filp);
  103.  
  104. out:
  105.     unlock_kernel();
  106.     return error;
  107. }
  108.